Skip to content

Conversation

@Nice3point
Copy link
Owner

@Nice3point Nice3point commented Jan 17, 2026

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Type Update Change
ModularPipelines nuget major 2.48.303.1.5
ModularPipelines.DotNet nuget major 2.48.303.1.5
ModularPipelines.Git nuget major 2.48.303.1.5
ModularPipelines.GitHub nuget major 2.48.303.1.5

Release Notes

thomhurst/ModularPipelines (ModularPipelines)

v3.1.5: 3.1.5

What's Changed

Full Changelog: thomhurst/ModularPipelines@v3.1.4...v3.1.5

v3.1.0: 3.1.0

What's Changed

Full Changelog: thomhurst/ModularPipelines@v3.0.125...v3.1.0

v3.0.124: 3.0.124

What's Changed

Full Changelog: thomhurst/ModularPipelines@v3.0.123...v3.0.124

v3.0.86: 3.0.86

What's Changed

Full Changelog: thomhurst/ModularPipelines@v3.0.84...v3.0.86

v3.0.1: 3.0.1

What's Changed

Full Changelog: thomhurst/ModularPipelines@v3.0.0...v3.0.1

v3.0.0: 3.0.0

ModularPipelines V3 Release Notes
Highlights
ASP.NET Core-Style Builder Pattern

No more callbacks. Direct property access, just like ASP.NET Core minimal APIs.

// Before (V2)
await PipelineHostBuilder.Create()
    .ConfigureAppConfiguration((context, builder) => { ... })
    .ConfigureServices((context, collection) => { ... })
    .ExecutePipelineAsync();

// After (V3)
var builder = Pipeline.CreateBuilder(args);
builder.Configuration.AddJsonFile("appsettings.json");
builder.Services.AddModule<BuildModule>();
await builder.Build().RunAsync();

If you've used ASP.NET Core, this feels instantly familiar.

Fluent Module Configuration

Configure module behavior with a clean, fluent API instead of scattered property overrides.

// Before (V2) - properties scattered across the class
protected internal override TimeSpan Timeout => TimeSpan.FromMinutes(5);
protected override AsyncRetryPolicy<string?> RetryPolicy => ...;
protected internal override Task<SkipDecision> ShouldSkip(...) => ...;

// After (V3) - everything in one place
protected override ModuleConfiguration Configure() => ModuleConfiguration.Create()
    .WithTimeout(TimeSpan.FromMinutes(5))
    .WithRetryCount(3)
    .WithSkipWhen(ctx => ctx.Git().Information.BranchName != "main"
        ? SkipDecision.Skip("Only runs on main")
        : SkipDecision.DoNotSkip)
    .Build();
Type-Safe Result Handling

Module results are now discriminated unions. Pattern matching gives you compile-time safety.

var result = await context.GetModule<BuildModule>();

return result switch
{
    ModuleResult<BuildOutput>.Success { Value: var output } => Deploy(output),
    ModuleResult.Skipped => null,
    ModuleResult.Failure { Exception: var ex } => throw ex,
    _ => null
};

Or use the simpler helpers for quick migrations:

if (result.IsSuccess)
{
    var value = result.ValueOrDefault;
}
New Features
Non-Generic Module Classes

New Module and SyncModule base classes for modules that don't return data.

// Async module - no return value needed
public class DeployModule : Module
{
    protected override async Task ExecuteModuleAsync(
        IModuleContext context, CancellationToken cancellationToken)
    {
        await context.Command.ExecuteCommandLineTool(...);
    }
}

// Sync module - no return value needed
public class LoggingModule : SyncModule
{
    protected override void ExecuteModule(
        IModuleContext context, CancellationToken cancellationToken)
    {
        context.Logger.LogInformation("Done!");
    }
}

Internally these use the None struct, which represents "nothing" and is semantically equivalent to null.

Dynamic Dependencies

Declare dependencies programmatically based on runtime conditions.

protected override void DeclareDependencies(IDependencyDeclaration deps)
{
    deps.DependsOn<RequiredModule>();
    deps.DependsOnOptional<OptionalModule>();
    deps.DependsOnIf<ProductionModule>(Environment.IsProduction);
}
Powerful Dependency Attributes
// Depend on all modules in a category
[DependsOnModulesInCategory("Build")]
public class TestModule : Module<TestResults> { }

// Depend on all modules with a tag
[DependsOnModulesWithTag("database")]
public class MigrationModule : Module<bool> { }
Conditional Execution Attributes
[RunOnLinux]
public class LinuxModule : Module<string> { }

[RunOnWindowsOnly]  // Skips on other platforms
public class WindowsOnlyModule : Module<string> { }

[SkipIf(typeof(IsNotMainBranchCondition))]
public class MainBranchModule : Module<string> { }

[RunIfAll(typeof(IsCI), typeof(IsMainBranch))]
public class CIMainModule : Module<string> { }
Module Tags and Categories

Organize modules for easier management.

[ModuleTag("critical")]
[ModuleTag("deployment")]
[ModuleCategory("Infrastructure")]
public class DeployModule : Module<DeployResult> { }
Pipeline Validation

Catch configuration errors before execution.

var validation = await builder.ValidateAsync();
if (validation.HasErrors)
{
    foreach (var error in validation.Errors)
    {
        Console.WriteLine($"[{error.Category}] {error.Message}");
    }
}
Plugin System

Create reusable pipeline extensions.

public class MyPlugin : IModularPipelinesPlugin
{
    public string Name => "MyPlugin";

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IMyService, MyService>();
    }

    public void ConfigurePipeline(PipelineBuilder builder)
    {
        builder.Services.AddModule<PluginModule>();
    }
}

[assembly: ModularPipelinesPlugin(typeof(MyPlugin))]
Enhanced Lifecycle Hooks

New overridable methods for fine-grained control.

protected override Task OnBeforeExecuteAsync(IModuleContext context, CancellationToken ct) { }
protected override Task OnAfterExecuteAsync(IModuleContext context, ModuleResult<T> result, CancellationToken ct) { }
protected override Task OnSkippedAsync(IModuleContext context, SkipDecision decision, CancellationToken ct) { }
protected override Task OnFailedAsync(IModuleContext context, Exception ex, CancellationToken ct) { }
Breaking Changes
Entry Point
V2 V3
PipelineHostBuilder.Create() Pipeline.CreateBuilder(args)
.ConfigureAppConfiguration(callback) builder.Configuration
.ConfigureServices(callback) builder.Services
.ConfigurePipelineOptions(callback) builder.Options
.AddModule<T>() on builder builder.Services.AddModule<T>()
.ExecutePipelineAsync() .Build().RunAsync()
Module API
V2 V3
IPipelineContext in ExecuteAsync IModuleContext
GetModule<T>() on module context.GetModule<T>()
Timeout property override Configure().WithTimeout()
RetryPolicy property override Configure().WithRetryCount()
ShouldSkip() method Configure().WithSkipWhen()
ShouldIgnoreFailures() method Configure().WithIgnoreFailures()
ModuleRunType.AlwaysRun Configure().WithAlwaysRun()
OnBeforeExecute() Configure().WithBeforeExecute() or OnBeforeExecuteAsync()
OnAfterExecute() Configure().WithAfterExecute() or OnAfterExecuteAsync()
Result Access
V2 V3
result.Value result.ValueOrDefault or pattern match
result.Exception result.ExceptionOrDefault or pattern match
result.ModuleResultType == ModuleResultType.Success result.IsSuccess or pattern match
Command Execution

Execution-related properties moved from tool options to a separate CommandExecutionOptions parameter:

V2 (on tool options) V3 (on CommandExecutionOptions)
WorkingDirectory WorkingDirectory
EnvironmentVariables EnvironmentVariables
ThrowOnNonZeroExitCode ThrowOnNonZeroExitCode
// V3: Pass execution options as second parameter
await context.DotNet().Build(
    new DotNetBuildOptions { Configuration = "Release" },
    new CommandExecutionOptions { WorkingDirectory = "/app" });
Removed Types
  • PipelineHostBuilder - Use Pipeline.CreateBuilder()
  • ModuleBase / ModuleBase<T> - Use Module<T>
Migration Path
Quick Migration (Minimal Changes)

The ExecutePipelineAsync() extension still exists:

var builder = Pipeline.CreateBuilder(args);
builder.Services.AddModule<MyModule>();
await builder.ExecutePipelineAsync();  // Still works

And ValueOrDefault provides backwards-compatible result access:

var result = await context.GetModule<BuildModule>();
var value = result.ValueOrDefault;  // Similar to old result.Value
Full Migration

For the cleanest code, adopt the new patterns:

  1. Use Pipeline.CreateBuilder(args) with direct property access
  2. Move module configuration to Configure() builder
  3. Change IPipelineContext to IModuleContext
  4. Move GetModule<T>() calls to context
  5. Use pattern matching for result handling

See the Migration Guide for detailed examples.

Upgrade Steps
  1. Update the NuGet package: dotnet add package ModularPipelines --version 3.0.0
  2. Fix compile errors using the migration tables above
  3. (Optional) Refactor to use new fluent APIs
  4. (Optional) Adopt new features like tags, categories, and conditional attributes
Getting Help
What's Changed

Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about these updates again.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate Bot.

Copilot AI review requested due to automatic review settings January 17, 2026 11:22
@Nice3point Nice3point added the maintenance ⚙️ Some regular maintenance updates label Jan 17, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates ModularPipelines and related packages from v2.48.30 to v3.0.1, a major version upgrade. However, it only updates package version references without including any of the required code changes to migrate from the v2 to v3 API.

Changes:

  • Updated ModularPipelines core package to v3.0.1
  • Updated ModularPipelines.DotNet, ModularPipelines.Git, and ModularPipelines.GitHub to v3.0.1

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 20 to 23
<PackageVersion Include="ModularPipelines" Version="3.0.1"/>
<PackageVersion Include="ModularPipelines.Git" Version="3.0.1"/>
<PackageVersion Include="ModularPipelines.GitHub" Version="3.0.1"/>
<PackageVersion Include="ModularPipelines.DotNet" Version="3.0.1"/>
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR updates ModularPipelines from v2.48.30 to v3.0.1, which is a major version upgrade with extensive breaking changes. However, the PR only updates the package versions without including the necessary code migrations.

According to the ModularPipelines v3 release notes, numerous breaking API changes require code updates throughout the build pipeline:

  1. Entry point changes: PipelineHostBuilder.Create() must be replaced with Pipeline.CreateBuilder(args) and callback-based configuration must be replaced with direct property access
  2. Context type changes: All IPipelineContext parameters must be changed to IModuleContext
  3. Module result access: The result API has changed - modules now return discriminated unions requiring pattern matching or use of ValueOrDefault
  4. Dependency retrieval: GetModule<T>() calls on module instances must be changed to context.GetModule<T>()
  5. Module lifecycle: Property overrides like ModuleRunType, ShouldIgnoreFailures(), and OnAfterExecute() must be migrated to the new fluent Configure() API or corresponding async methods

Without these code changes, the build will fail to compile. The existing codebase in build/Program.cs and all module files (build/Modules/*.cs) still use the v2 API patterns and are incompatible with v3.

Suggested change
<PackageVersion Include="ModularPipelines" Version="3.0.1"/>
<PackageVersion Include="ModularPipelines.Git" Version="3.0.1"/>
<PackageVersion Include="ModularPipelines.GitHub" Version="3.0.1"/>
<PackageVersion Include="ModularPipelines.DotNet" Version="3.0.1"/>
<PackageVersion Include="ModularPipelines" Version="2.48.30"/>
<PackageVersion Include="ModularPipelines.Git" Version="2.48.30"/>
<PackageVersion Include="ModularPipelines.GitHub" Version="2.48.30"/>
<PackageVersion Include="ModularPipelines.DotNet" Version="2.48.30"/>

Copilot uses AI. Check for mistakes.
@Nice3point Nice3point force-pushed the renovate/major-modularpipelines branch 3 times, most recently from 2c7c49a to fd3d604 Compare January 19, 2026 01:57
@Nice3point Nice3point force-pushed the renovate/major-modularpipelines branch from fd3d604 to 7e7c480 Compare January 19, 2026 12:55
@Nice3point Nice3point changed the title Update ModularPipelines to v3 (major) Update ModularPipelines to v3 (major) - abandoned Jan 20, 2026
@Nice3point
Copy link
Owner Author

Autoclosing Skipped

This PR has been flagged for autoclosing. However, it is being skipped due to the branch being already modified. Please close/delete it manually or report a bug if you think this is in error.

@Nice3point Nice3point closed this Jan 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintenance ⚙️ Some regular maintenance updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants